package xyz.bali16.module.notification.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.starblues.spring.MainApplicationContext;
import com.gitee.starblues.spring.SpringBeanFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import xyz.bali16.application.core.enums.ApiEnum;
import xyz.bali16.application.core.exception.BusinessException;
import xyz.bali16.application.core.model.Result;
import xyz.bali16.application.core.utils.AuthUtils;
import xyz.bali16.application.entity.Role;
import xyz.bali16.application.entity.User;
import xyz.bali16.application.service.UserService;
import xyz.bali16.module.notification.entity.Notification;
import xyz.bali16.module.notification.entity.NotificationDTO;
import xyz.bali16.module.notification.model.NotificationAddParam;
import xyz.bali16.module.notification.model.NotificationPageParam;
import xyz.bali16.module.notification.model.NotificationUpdateParam;
import xyz.bali16.module.notification.service.NotificationService;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static xyz.bali16.application.core.model.Result.*;
import static xyz.bali16.application.core.model.Result.failure;
import static xyz.bali16.module.notification.utils.ResultUtils.errorLog;

/**
 * @author bali2 on 9/3/2023.
 * @version 1.0
 */
@RestController
@RequestMapping(BaseController.API + "notification")
@Api(tags = "消息接口")
@AllArgsConstructor

public class NotificationController extends BaseController {
    public static final Logger logger = LoggerFactory.getLogger(NotificationController.class);
    @Autowired
    NotificationService notificationService;
    @Autowired
    private MainApplicationContext context;

    @GetMapping
    @ApiOperation("分页条件查询消息")
    //@PreAuthorize("@auth.permission('plugin:notification:query')")
    public Result<IPage<Notification>> pageQuery(@Valid NotificationPageParam param) {
        IPage<Notification> notificationIPage = notificationService.getPage(param);
        return success(ApiEnum.GET_SUCCESS, notificationIPage);
    }
    
    @GetMapping("/unreadcount")
    @ApiOperation("未读消息")
    //@PreAuthorize("@auth.permission('plugin:notification:query')")
    public Result<Integer> count() {
        String username = AuthUtils.getCurrentUsername();
        SpringBeanFactory factory = context.getSpringBeanFactory();
        UserService userService = factory.getBean(UserService.class);
        User user = userService.getByUsername(username);
        if (user == null) return failure("不存在该用户");
        Integer unreadCount = notificationService.unreadCount(user.getUserId());
        return success(unreadCount);
    }

    @GetMapping("/{id}")
    public Result<String> readNotification(@PathVariable("id") String id) throws Exception {
        try {
            String username = AuthUtils.getCurrentUsername();
            SpringBeanFactory factory = context.getSpringBeanFactory();
            UserService userService = factory.getBean(UserService.class);
            User user = userService.getByUsername(username);
            NotificationDTO notificationDTO = notificationService.read(id, user);
            return success(ApiEnum.GET_SUCCESS, notificationDTO.getOuterId());
        } catch (Exception e) {
            errorLog(logger, e, "修改消息状态失败. {}", e.getMessage());
            return failure(ApiEnum.UPDATE_ERROR, "失败: ", e);
        }
    }

    @PostMapping("/removeAll")
    public Result<String> removeAllNotifications(@RequestParam(name = "all", defaultValue = "0") Integer all) throws Exception {
        String username = AuthUtils.getCurrentUsername();
        SpringBeanFactory factory = context.getSpringBeanFactory();
        UserService userService = factory.getBean(UserService.class);
        User user = userService.getByUsername(username);
        if (user == null) {
            throw new BusinessException("你还未登录");
        }

        if (all == null || all != 1) {
            return failure("出现问题");
        } else if (all == 1) {
            notificationService.removeAllByUserId(user.getUserId());
        }
        return success("删除成功");
    }
    @PostMapping("/readAll")
    public Result<String> readAllNotifications(@RequestParam(name = "all", defaultValue = "0") Integer all) throws Exception {
        String username = AuthUtils.getCurrentUsername();
        SpringBeanFactory factory = context.getSpringBeanFactory();
        UserService userService = factory.getBean(UserService.class);
        User user = userService.getByUsername(username);
        if (user == null) {
            throw new BusinessException("你还未登录");
        }

        if (all == null || all != 1) {
            return failure("出现问题");
        } else if (all == 1) {
            notificationService.readAllByUserId(user.getUserId());
        }
        return success("阅读成功");
    }

    @PostMapping
    //@PreAuthorize("@auth.permission('plugin:notification:add')")
    @ApiOperation("添加消息")
    public Result<String> add(@RequestBody @Valid NotificationAddParam param) {
        try {
            notificationService.add(param);
            return response(ApiEnum.ADD_SUCCESS);
        } catch (Exception e) {
            errorLog(logger, e, "新增消息失败 {}", e.getMessage());
            return failure(ApiEnum.ADD_ERROR, "新增消息失败", e);
        }
    }

    @PutMapping
    //@PreAuthorize("@auth.permission('plugin:notification:update')")
    @ApiOperation("修改消息")
    public Result<String> update(@RequestBody @Valid NotificationUpdateParam param) {
        try {
            notificationService.update(param);
            return response(ApiEnum.UPDATE_SUCCESS);
        } catch (Exception e) {
            errorLog(logger, e, "更新消息 '{}' 信息失败 {}", param.getId(), e.getMessage());
            return failure(ApiEnum.UPDATE_ERROR, "更新消息失败", e);
        }
    }

    @PutMapping("{notificationId}/{status}")
    //@PreAuthorize("@auth.permission('plugin:notification:update')")
    @ApiOperation("修改消息状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "notificationId", value = "消息id", paramType = "path", required = true),
            @ApiImplicitParam(name = "status", value = "状态（1已读, 0未读）", paramType = "path", required = true)
    })
    public Result<Role> updateStatus(@PathVariable("notificationId") String notificationId, @PathVariable("status") Integer status) {
        String message = status == 1 ? "已读" : "未读";
        try {
            notificationService.updateStatus(notificationId, status);
            return response(ApiEnum.UPDATE_SUCCESS, message + "成功");
        } catch (Exception e) {
            errorLog(logger, e, "修改消息状态失败. {}", e.getMessage());
            return failure(ApiEnum.UPDATE_ERROR, message + "失败: ", e);
        }
    }

    @DeleteMapping("/{notificationId}")
    //@PreAuthorize("@auth.permission('plugin:notification:delete')")
    @ApiOperation("删除消息")
    @ApiImplicitParam(name = "NotificationId", value = "消息id", paramType = "path", required = true)
    public Result<String> delete(@PathVariable("notificationId") String notificationId) {
        try {
            notificationService.delete(notificationId);
            return response(ApiEnum.DELETE_SUCCESS);
        } catch (Exception e) {
            errorLog(logger, e, "删除消息 '{}' 失败. {}", notificationId, e.getMessage());
            return failure(ApiEnum.DELETE_ERROR, e);
        }
    }

}
